Chuyển đổi từ lập trình CPU tuần tự sang lập trình GPU đòi hỏi một sự thay đổi tư duy: từ lặp từng phần tử sang thực thi theo khối. Chúng ta không còn xem dữ liệu như một luồng các giá trị vô hướng, mà là tập hợp các "khối" được lập kế hoạch để tận dụng băng thông phần cứng.
1. Bị giới hạn bởi bộ nhớ so với bị giới hạn bởi tính toán
Ngưỡng giới hạn của một kernel được xác định bởi tỷ lệ giữa các phép toán số học và truy cập bộ nhớ. Phép cộng vector thường bị giới hạn bởi bộ nhớ vì nó chỉ thực hiện một phép cộng cho mỗi ba thao tác truy cập bộ nhớ (2 lần tải, 1 lần lưu). Phần cứng dành nhiều thời gian chờ đợi DRAM hơn là thực hiện tính toán.
2. Vai trò của BLOCK_SIZE
BLOCK_SIZE xác định mức độ chi tiết của tính song song. Nếu quá nhỏ, chúng ta sẽ không tận dụng hết các kênh thực thi rộng rãi của GPU. Kích thước tối ưu đảm bảo đủ "công việc đang thực hiện" để bão hòa băng thông bộ nhớ.
3. Giấu độ trễ thông qua mức độ chiếm dụng
Mức độ chiếm dụng là số lượng khối hoạt động trên GPU. Mặc dù không phải là mục tiêu cuối cùng, nhưng nó giúp bộ lập lịch chuyển sang một khối mới để thực hiện tính toán trong khi một khối khác đang chờ lấy dữ liệu từ VRAM với độ trễ cao.
4. Tận dụng phần cứng
Để tối đa hóa hiệu suất, chúng ta phải điều chỉnh BLOCK_SIZE theo các quy tắc ghép nối bộ nhớ của kiến trúc GPU, đảm bảo rằng các luồng liên tiếp truy cập vào các địa chỉ bộ nhớ liền kề nhau.